#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
图片像素查看工具
功能：加载图片，鼠标悬停显示像素点信息
"""

import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import os

# 导入ttkbootstrap美化
try:
    import ttkbootstrap as ttk
    from ttkbootstrap.constants import *
    from ttkbootstrap.style import Style
    from ttkbootstrap.icons import Icon
    BOOTSTRAP_AVAILABLE = True
except ImportError:
    BOOTSTRAP_AVAILABLE = False

# 导入配置（自动配置Python路径）
from settings import BASE_DIR
from utils.window_utils import calculate_window_size, center_window

class PixelViewerWindow:
    """像素查看器窗口"""
    
    def __init__(self, parent=None):
        """初始化窗口"""
        # 创建独立窗口
        if parent:
            if BOOTSTRAP_AVAILABLE:
                self.window = tk.Toplevel(parent)
                # 尝试获取父窗口的样式
                if hasattr(parent, 'style'):
                    self.style = parent.style
                else:
                    self.style = Style(theme='cosmo')
            else:
                self.window = tk.Toplevel(parent)
        else:
            if BOOTSTRAP_AVAILABLE:
                self.style = Style(theme='cosmo')
                self.window = self.style.master
            else:
                self.window = tk.Tk()
        
        if BOOTSTRAP_AVAILABLE:
            self.window.title("图片像素查看工具")
        else:
            self.window.title("图片像素查看工具")
        
        # 根据屏幕分辨率自适应窗口大小
        width, height = calculate_window_size(
            width_percent=0.7,
            height_percent=0.7,
            min_width=800,
            max_width=1200,
            min_height=600,
            max_height=900
        )
        
        # 居中显示窗口
        center_window(self.window, width, height)
        
        self.window.minsize(800, 600)
        
        # 图片相关变量
        self.image = None
        self.photo = None
        self.image_path = None
        self.scale_factor = 1.0
        
        # 创建界面
        self.create_widgets()
        
        # 绑定鼠标事件
        self.bind_events()
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = tk.Frame(self.window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 工具栏
        toolbar = tk.Frame(main_frame)
        toolbar.pack(fill=tk.X, pady=(0, 10))
        
        # 按钮
        self.load_btn = tk.Button(toolbar, text="加载图片", command=self.load_image, 
                                 font=("Arial", 12), bg="#4CAF50", fg="white")
        self.load_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        self.zoom_in_btn = tk.Button(toolbar, text="放大", command=self.zoom_in,
                                    font=("Arial", 12), bg="#2196F3", fg="white")
        self.zoom_in_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.zoom_out_btn = tk.Button(toolbar, text="缩小", command=self.zoom_out,
                                     font=("Arial", 12), bg="#FF9800", fg="white")
        self.zoom_out_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.reset_zoom_btn = tk.Button(toolbar, text="重置缩放", command=self.reset_zoom,
                                       font=("Arial", 12), bg="#9C27B0", fg="white")
        self.reset_zoom_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        # 信息显示区域
        info_frame = tk.Frame(toolbar)
        info_frame.pack(side=tk.RIGHT)
        
        self.info_label = tk.Label(info_frame, text="请加载图片", 
                                  font=("Arial", 12), fg="#666")
        self.info_label.pack()
        
        # 图片显示区域
        self.canvas = tk.Canvas(main_frame, bg="white", cursor="crosshair")
        self.canvas.pack(fill=tk.BOTH, expand=True)
        
        # 状态栏
        status_frame = tk.Frame(main_frame)
        status_frame.pack(fill=tk.X, pady=(10, 0))
        
        self.status_label = tk.Label(status_frame, text="就绪", 
                                    font=("Arial", 10), fg="#666", anchor=tk.W)
        self.status_label.pack(side=tk.LEFT)
        
        # 像素信息显示
        self.pixel_info = tk.Label(status_frame, text="", 
                                  font=("Arial", 10), fg="#333", anchor=tk.E)
        self.pixel_info.pack(side=tk.RIGHT)
    
    def bind_events(self):
        """绑定鼠标事件"""
        self.canvas.bind("<Motion>", self.on_mouse_move)
        self.canvas.bind("<Button-1>", self.on_mouse_click)
        self.canvas.bind("<MouseWheel>", self.on_mouse_wheel)
        self.canvas.bind("<Button-4>", self.on_mouse_wheel)  # Linux
        self.canvas.bind("<Button-5>", self.on_mouse_wheel)  # Linux
    
    def load_image(self):
        """加载图片"""
        file_path = filedialog.askopenfilename(
            title="选择图片文件",
            filetypes=[
                ("图片文件", "*.png *.jpg *.jpeg *.bmp *.gif *.tiff"),
                ("PNG文件", "*.png"),
                ("JPEG文件", "*.jpg *.jpeg"),
                ("所有文件", "*.*")
            ]
        )
        
        if file_path:
            try:
                self.image_path = file_path
                self.image = Image.open(file_path)
                self.scale_factor = 1.0
                self.display_image()
                self.update_info()
                self.status_label.config(text=f"已加载: {os.path.basename(file_path)}")
            except Exception as e:
                messagebox.showerror("错误", f"无法加载图片: {str(e)}")
    
    def display_image(self):
        """显示图片"""
        if self.image is None:
            return
        
        # 计算缩放后的尺寸
        width = int(self.image.width * self.scale_factor)
        height = int(self.image.height * self.scale_factor)
        
        # 缩放图片
        resized_image = self.image.resize((width, height), Image.Resampling.LANCZOS)
        self.photo = ImageTk.PhotoImage(resized_image)
        
        # 清除画布并显示图片
        self.canvas.delete("all")
        self.canvas.config(scrollregion=(0, 0, width, height))
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo)
    
    def update_info(self):
        """更新信息显示"""
        if self.image:
            info_text = f"尺寸: {self.image.width}×{self.image.height} | 缩放: {self.scale_factor:.2f}x"
            self.info_label.config(text=info_text)
        else:
            self.info_label.config(text="请加载图片")
    
    def on_mouse_move(self, event):
        """鼠标移动事件"""
        if self.image is None:
            return
        
        # 计算在原始图片中的坐标
        canvas_x = self.canvas.canvasx(event.x)
        canvas_y = self.canvas.canvasy(event.y)
        
        # 转换为图片坐标
        img_x = int(canvas_x / self.scale_factor)
        img_y = int(canvas_y / self.scale_factor)
        
        # 检查坐标是否在图片范围内
        if 0 <= img_x < self.image.width and 0 <= img_y < self.image.height:
            # 获取像素颜色
            pixel = self.image.getpixel((img_x, img_y))
            
            # 格式化颜色信息
            if isinstance(pixel, tuple):
                if len(pixel) == 3:  # RGB
                    color_info = f"RGB({pixel[0]}, {pixel[1]}, {pixel[2]})"
                    hex_color = f"#{pixel[0]:02X}{pixel[1]:02X}{pixel[2]:02X}"
                elif len(pixel) == 4:  # RGBA
                    color_info = f"RGBA({pixel[0]}, {pixel[1]}, {pixel[2]}, {pixel[3]})"
                    hex_color = f"#{pixel[0]:02X}{pixel[1]:02X}{pixel[2]:02X}{pixel[3]:02X}"
                else:
                    color_info = str(pixel)
                    hex_color = ""
            else:  # 灰度图
                color_info = f"灰度({pixel})"
                hex_color = f"#{pixel:02X}{pixel:02X}{pixel:02X}"
            
            # 更新像素信息显示
            pixel_text = f"位置: ({img_x}, {img_y}) | {color_info}"
            if hex_color:
                pixel_text += f" | {hex_color}"
            
            self.pixel_info.config(text=pixel_text)
            
            # 更新状态栏
            self.status_label.config(text=f"鼠标位置: ({img_x}, {img_y})")
        else:
            self.pixel_info.config(text="")
            self.status_label.config(text="鼠标在图片外")
    
    def on_mouse_click(self, event):
        """鼠标点击事件"""
        if self.image is None:
            return
        
        # 计算在原始图片中的坐标
        canvas_x = self.canvas.canvasx(event.x)
        canvas_y = self.canvas.canvasy(event.y)
        
        # 转换为图片坐标
        img_x = int(canvas_x / self.scale_factor)
        img_y = int(canvas_y / self.scale_factor)
        
        # 检查坐标是否在图片范围内
        if 0 <= img_x < self.image.width and 0 <= img_y < self.image.height:
            # 获取像素颜色
            pixel = self.image.getpixel((img_x, img_y))
            
            # 创建详细信息窗口
            self.show_pixel_details(img_x, img_y, pixel)
    
    def show_pixel_details(self, x, y, pixel):
        """显示像素详细信息"""
        detail_window = tk.Toplevel(self.window)
        detail_window.title(f"像素详细信息 - ({x}, {y})")
        detail_window.geometry("400x300")
        detail_window.resizable(False, False)
        
        # 使窗口居中
        detail_window.transient(self.window)
        detail_window.grab_set()
        
        # 主框架
        main_frame = tk.Frame(detail_window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # 标题
        title_label = tk.Label(main_frame, text=f"像素位置: ({x}, {y})", 
                              font=("Arial", 14, "bold"))
        title_label.pack(pady=(0, 20))
        
        # 颜色信息
        color_frame = tk.LabelFrame(main_frame, text="颜色信息", font=("Arial", 12))
        color_frame.pack(fill=tk.X, pady=(0, 10))
        
        if isinstance(pixel, tuple):
            if len(pixel) == 3:  # RGB
                tk.Label(color_frame, text=f"RGB: {pixel[0]}, {pixel[1]}, {pixel[2]}", 
                        font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
                hex_color = f"#{pixel[0]:02X}{pixel[1]:02X}{pixel[2]:02X}"
                tk.Label(color_frame, text=f"十六进制: {hex_color}", 
                        font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
                
                # 颜色预览
                color_preview = tk.Frame(color_frame, bg=hex_color, width=50, height=30)
                color_preview.pack(padx=10, pady=5)
                
            elif len(pixel) == 4:  # RGBA
                tk.Label(color_frame, text=f"RGBA: {pixel[0]}, {pixel[1]}, {pixel[2]}, {pixel[3]}", 
                        font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
                hex_color = f"#{pixel[0]:02X}{pixel[1]:02X}{pixel[2]:02X}{pixel[3]:02X}"
                tk.Label(color_frame, text=f"十六进制: {hex_color}", 
                        font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
                
                # 颜色预览
                color_preview = tk.Frame(color_frame, bg=hex_color, width=50, height=30)
                color_preview.pack(padx=10, pady=5)
        else:  # 灰度图
            tk.Label(color_frame, text=f"灰度值: {pixel}", 
                    font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
            hex_color = f"#{pixel:02X}{pixel:02X}{pixel:02X}"
            tk.Label(color_frame, text=f"十六进制: {hex_color}", 
                    font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
            
            # 颜色预览
            color_preview = tk.Frame(color_frame, bg=hex_color, width=50, height=30)
            color_preview.pack(padx=10, pady=5)
        
        # 图片信息
        info_frame = tk.LabelFrame(main_frame, text="图片信息", font=("Arial", 12))
        info_frame.pack(fill=tk.X, pady=(0, 10))
        
        tk.Label(info_frame, text=f"图片尺寸: {self.image.width} × {self.image.height}", 
                font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
        tk.Label(info_frame, text=f"图片模式: {self.image.mode}", 
                font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
        tk.Label(info_frame, text=f"当前缩放: {self.scale_factor:.2f}x", 
                font=("Arial", 11)).pack(anchor=tk.W, padx=10, pady=5)
        
        # 关闭按钮
        close_btn = tk.Button(main_frame, text="关闭", command=detail_window.destroy,
                             font=("Arial", 12), bg="#f44336", fg="white")
        close_btn.pack(pady=(20, 0))
    
    def zoom_in(self):
        """放大图片"""
        if self.image:
            self.scale_factor *= 1.2
            self.display_image()
            self.update_info()
    
    def zoom_out(self):
        """缩小图片"""
        if self.image:
            self.scale_factor /= 1.2
            self.display_image()
            self.update_info()
    
    def reset_zoom(self):
        """重置缩放"""
        if self.image:
            self.scale_factor = 1.0
            self.display_image()
            self.update_info()
    
    def on_mouse_wheel(self, event):
        """鼠标滚轮事件"""
        if self.image:
            if event.delta > 0 or event.num == 4:  # 向上滚动
                self.zoom_in()
            elif event.delta < 0 or event.num == 5:  # 向下滚动
                self.zoom_out()
    
    def show(self):
        """显示窗口"""
        self.window.deiconify()
        self.window.lift()
        self.window.focus_force()


def open_pixel_viewer(parent=None):
    """打开像素查看器（供外部调用）"""
    viewer = PixelViewerWindow(parent)
    return viewer


def main():
    """主函数（独立运行时使用）"""
    root = tk.Tk()
    viewer = PixelViewerWindow(None)
    viewer.window = root
    root.mainloop()


if __name__ == "__main__":
    main()

